package com.shanzmoo.merchant.manage.api.manager.merchant;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shanzmoo.base.bean.PageRespBase;
import com.shanzmoo.base.bean.SHttpResponse;
import com.shanzmoo.base.util.CollectionUtil;
import com.shanzmoo.base.util.JYFException;
import com.shanzmoo.core.manager.base.AliSmsManager;
import com.shanzmoo.db.module.base.service.ISAreaService;
import com.shanzmoo.db.module.merchant.domain.base.BaseInfoDomain;
import com.shanzmoo.db.module.merchant.domain.query.MerchantInfoQuery;
import com.shanzmoo.db.module.merchant.domain.query.MerchantShopQuery;
import com.shanzmoo.db.module.merchant.domain.query.MerchantTerminalQuery;
import com.shanzmoo.db.module.merchant.domain.vo.MerchantInfoDetailVo;
import com.shanzmoo.db.module.merchant.domain.vo.MerchantShopVo;
import com.shanzmoo.db.module.merchant.domain.vo.MerchantTerminalVo;
import com.shanzmoo.db.module.merchant.entity.MerchantInfoEntity;
import com.shanzmoo.db.module.merchant.entity.MerchantOperLogEntity;
import com.shanzmoo.db.module.merchant.entity.MerchantShopEntity;
import com.shanzmoo.db.module.merchant.entity.MerchantTerminalEntity;
import com.shanzmoo.db.module.merchant.service.*;
import com.shanzmoo.db.module.pay.service.ISBankService;
import com.shanzmoo.db.module.pay.service.ISBusinessService;
import com.shanzmoo.merchant.manage.api.util.SecurityUtil;
import com.shanzmoo.pay.domain.request.storeRequest.SaobeiStoreAddRequest;
import com.shanzmoo.pay.domain.request.terminalRequest.SaobeiTerminalAddRequest;
import com.shanzmoo.pay.domain.response.storeResponse.SaobeiStoreAddResponse;
import com.shanzmoo.pay.domain.response.terminalResponse.SaobeiTerminalAddResponse;
import com.shanzmoo.pay.manager.SaobeiMerchantManager;
import com.shanzmoo.pay.manager.SaobeiStoreManager;
import com.shanzmoo.pay.manager.SaobeiTerminalManager;
import com.shanzmoo.pay.util.ApiConstants;
import com.shanzmoo.pay.util.RandomUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component
@RequiredArgsConstructor
public class MerchantInfoManager {
    // 入驻商户操作服务
    private final IMerchantInfoService iMerchantInfoService;
    // 商户门店操作信息
    private final IMerchantShopService iMerchantShopService;
    // 商户台卡操作信息
    private final IMerchantTerminalService iMerchantTerminalService;
    // 商户操作日志操作信息
    private final IMerchantOperLogService iMerchantOperLogService;
    // 扫呗门店接口管理
    private final SaobeiStoreManager saobeiStoreManager;
    // 扫呗终端（台卡）接口管理
    private final SaobeiTerminalManager saobeiTerminalManager;

    /**
     * 根据查询条件查询入驻商户明细信息
     *
     * @param query
     * @return
     */
    public SHttpResponse<MerchantInfoDetailVo> selectMerchantInfo(MerchantInfoQuery query) {
        // 0、获取当前用户
        query.setCode(SecurityUtil.getCurrentUser().getMerchantCode());
        log.info(" 当前登录人信息为：{}", query.getCode());
        // 1、查询数据库数据信息
        MerchantInfoEntity merchantInfoEntity = iMerchantInfoService.lambdaQuery()
                .eq(StringUtils.isNotBlank(query.getCode()), MerchantInfoEntity::getCode, query.getCode())
                .eq(StringUtils.isNotBlank(query.getMobile()), MerchantInfoEntity::getMobile, query.getMobile())
                .one();
        // 2、组装返回值信息
        MerchantInfoDetailVo merchantInfoDetailVo = new MerchantInfoDetailVo();
        BeanUtils.copyProperties(merchantInfoEntity, merchantInfoDetailVo);
        return SHttpResponse.ok(merchantInfoDetailVo);
    }

    /**
     * 保存/修改门店信息
     *
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SHttpResponse<Boolean> saveMerchantShopEntity(@RequestBody MerchantShopVo merchantShop) throws JYFException {
        // 1、初始化门店信息
        boolean isNew = merchantShop.getId() == null ? true : false;
        MerchantShopEntity merchantShopEntity = new MerchantShopEntity();
        BeanUtils.copyProperties(merchantShop, merchantShopEntity);
        merchantShopEntity.setCode(merchantShop.getMerchantCode().substring(0, merchantShop.getMerchantCode().length() > 18 ? 18 : merchantShop.getMerchantCode().length()));
        // 2、保存/修改门店信息
        boolean result = iMerchantShopService.saveOrUpdate(merchantShopEntity);
        if (isNew){
            // 新增
            // 3、推送保存或修改门店信息到扫呗
            SaobeiStoreAddRequest addRequest = initSaobeiStoreAddRequest(merchantShopEntity);
            SaobeiStoreAddResponse addResponse = saobeiStoreManager.addStore(addRequest);
            if (!"01".equals(addResponse.getReturn_code()) || ("01".equals(addResponse.getReturn_code()) && !"01".equals(addResponse.getResult_code()))) {
                log.error("扫呗创建门店异常，检查返回结果信息为：{}", JSONObject.toJSONString(addResponse));
                throw new JYFException(addResponse.getReturn_msg());
            } else {
                log.info("扫呗创建门店成功");
                // 成功，则更新门店编码
                boolean update = iMerchantShopService.lambdaUpdate()
                        .eq(MerchantShopEntity::getId, merchantShopEntity.getId())
                        .set(MerchantShopEntity::getCode, addResponse.getStore_code())
                        .update();
            }
        }
        // 4、写操作日志
        BaseInfoDomain baseInfoDomain = new BaseInfoDomain();
        baseInfoDomain.setCode(merchantShop.getMerchantCode());
        MerchantOperLogEntity merchantOperLogEntity = initMerchantOperLog(baseInfoDomain, "创建门店信息", 10);
        iMerchantOperLogService.save(merchantOperLogEntity);
        return SHttpResponse.ok(result);
    }

    /**
     * 分页查询门店信息
     *
     * @return
     */
    public SHttpResponse<PageRespBase<MerchantShopVo>> selectMerchantShop(@RequestBody MerchantShopQuery query) {
        Page<MerchantShopEntity> page = iMerchantShopService.lambdaQuery()
                .eq(query.getId() != null, MerchantShopEntity::getId, query.getCode())
                .eq(StringUtils.isNotBlank(query.getMerchantCode()), MerchantShopEntity::getMerchantCode, query.getMerchantCode())
                .eq(StringUtils.isNotBlank(query.getCode()), MerchantShopEntity::getCode, query.getCode())
                .like(StringUtils.isNotBlank(query.getName()), MerchantShopEntity::getName, query.getName())
                .between(query.getStartTime() != null, MerchantShopEntity::getCreateTime, query.getStartTime(), query.getEndTime())
                .orderByDesc(MerchantShopEntity::getCreateTime)
                .page(new Page<>(query.getPageNum(), query.getPageSize()));
        // 3、组装数据信息
        PageRespBase<MerchantShopVo> respBase = new PageRespBase<MerchantShopVo>();
        respBase.setCurrPage(query.getPageNum());
        respBase.setPageSize(query.getPageSize());
        respBase.setTotalCount(page.getTotal());
        respBase.setTotalPage(page.getTotal() % page.getSize() == 0 ? page.getTotal() / page.getSize() : page.getTotal() / page.getSize() + 1);
        List<MerchantShopVo> merchantShopVos = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(page.getRecords())) {
            page.getRecords().forEach(item -> {
                MerchantShopVo merchantShopVo = new MerchantShopVo();
                BeanUtils.copyProperties(item, merchantShopVo);
                merchantShopVos.add(merchantShopVo);
            });
        }
        respBase.setList(merchantShopVos);
        return SHttpResponse.ok(respBase);
    }

    /**
     * 查询门店详情信息
     *
     * @return
     */
    public SHttpResponse<MerchantShopVo> selectMerchantShopDetail(@RequestParam(value = "id") Integer id) {
        // 1、通过ID查询门店信息
        MerchantShopEntity merchantShopEntity = iMerchantShopService.getById(id);
        // 2、组装返回数据
        if (merchantShopEntity != null) {
            MerchantShopVo merchantShopVo = new MerchantShopVo();
            BeanUtils.copyProperties(merchantShopEntity, merchantShopVo);
            return SHttpResponse.ok(merchantShopVo);
        }
        return SHttpResponse.fail(100002, "门店信息不存在");
    }


    /**
     * 保存/修改商户台卡信息
     *
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SHttpResponse<Boolean> saveMerchantTerminal(@RequestBody MerchantTerminalVo merchantTerminal) throws JYFException {
        // 1、初始化商户台卡信息
        boolean isNew = merchantTerminal.getId() == null ? true : false;
        MerchantTerminalEntity merchantTerminalEntity = new MerchantTerminalEntity();
        BeanUtils.copyProperties(merchantTerminal, merchantTerminalEntity);
        // 2、保存/修改商户台卡信息
        boolean result = iMerchantTerminalService.saveOrUpdate(merchantTerminalEntity);
        if (isNew) {
            // 新增
            // 3、推送保存或修改台卡信息到扫呗
            SaobeiTerminalAddRequest addRequest = initSaobeiTerminalAddRequest(merchantTerminal);
            SaobeiTerminalAddResponse addResponse = saobeiTerminalManager.addTerminal(addRequest);
            if (!"01".equals(addResponse.getReturn_code()) || ("01".equals(addResponse.getReturn_code()) && !"01".equals(addResponse.getResult_code()))) {
                log.error("扫呗创建商户台卡异常，检查返回结果信息为：{}", JSONObject.toJSONString(addResponse));
                throw new JYFException(addResponse.getReturn_msg());
            } else {
                log.info("扫呗创建商户台卡成功，返回信息为：{}", JSONObject.toJSONString(addResponse));
                // 更新当前台卡信息
                boolean update = iMerchantTerminalService.lambdaUpdate()
                        .eq(MerchantTerminalEntity::getId, merchantTerminalEntity.getId())
                        .set(MerchantTerminalEntity::getTerminalId, addResponse.getTerminal_id())
                        .update();
            }
        }
        // 4、写操作日志
        BaseInfoDomain baseInfoDomain = new BaseInfoDomain();
        baseInfoDomain.setCode(merchantTerminal.getMerchantNo());
        MerchantOperLogEntity merchantOperLogEntity = initMerchantOperLog(baseInfoDomain, "创建商户台卡信息", 11);
        iMerchantOperLogService.save(merchantOperLogEntity);
        return SHttpResponse.ok(result);
    }

    /**
     * 开通或关闭商户台卡信息
     *
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SHttpResponse<Boolean> updateMerchantTerminal(@RequestBody MerchantTerminalVo merchantTerminal) {
        // 1、更新台卡信息
        boolean update = iMerchantTerminalService.lambdaUpdate()
                .eq(MerchantTerminalEntity::getId, merchantTerminal.getId())
                .set(MerchantTerminalEntity::getDeleted, merchantTerminal.getDeleted())
                .set(MerchantTerminalEntity::getUpdateTime, LocalDateTime.now())
                // 更新修改人
                .set(MerchantTerminalEntity::getUpdateUser, "111")
                .update();
        return update ? SHttpResponse.ok(true) : SHttpResponse.fail(100006, "更新台卡信息失败");
    }

    /**
     * 分页查询商户台卡信息
     *
     * @return
     */
    public SHttpResponse<PageRespBase<MerchantTerminalVo>> selectMerchantTerminal(@RequestBody MerchantTerminalQuery query) {
        // 1、按照条件查询商户台卡信息
        Page<MerchantTerminalEntity> page = iMerchantTerminalService.lambdaQuery()
                .eq(StringUtils.isNotBlank(query.getStoreCode()), MerchantTerminalEntity::getStoreCode, query.getStoreCode())
                .eq(StringUtils.isNotBlank(query.getMerchantNo()), MerchantTerminalEntity::getMerchantNo, query.getMerchantNo())
                .orderByDesc(MerchantTerminalEntity::getCreateTime)
                .page(new Page<>(query.getPageNum(), query.getPageSize()));
        // 2、组装数据信息
        PageRespBase<MerchantTerminalVo> respBase = new PageRespBase<MerchantTerminalVo>();
        respBase.setCurrPage(query.getPageNum());
        respBase.setPageSize(query.getPageSize());
        respBase.setTotalCount(page.getTotal());
        respBase.setTotalPage(page.getTotal() % page.getSize() == 0 ? page.getTotal() / page.getSize() : page.getTotal() / page.getSize() + 1);
        List<MerchantTerminalVo> merchantTerminalVos = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(page.getRecords())) {
            page.getRecords().forEach(item -> {
                MerchantTerminalVo merchantTerminalVo = new MerchantTerminalVo();
                BeanUtils.copyProperties(item, merchantTerminalVo);
                merchantTerminalVos.add(merchantTerminalVo);
            });
        }
        respBase.setList(merchantTerminalVos);
        return SHttpResponse.ok(respBase);
    }

    /**
     * 查询商户台卡详情信息
     *
     * @return
     */
    public SHttpResponse<MerchantTerminalVo> selectMerchantTerminalDetail(@RequestParam(value = "id") Integer id) {
        // 1、通过ID查询商户台卡信息
        MerchantTerminalEntity merchantTerminalEntity = iMerchantTerminalService.getById(id);
        // 2、组装返回数据
        if (merchantTerminalEntity != null) {
            MerchantTerminalVo merchantTerminalVo = new MerchantTerminalVo();
            BeanUtils.copyProperties(merchantTerminalEntity, merchantTerminalVo);
            return SHttpResponse.ok(merchantTerminalVo);
        }
        return SHttpResponse.fail(100002, "商户台卡信息不存在");
    }


    /********************************************************* private **********************************************************/

    /**
     * 初始化商户台卡信息
     *
     * @param merchantTerminal
     * @return
     */
    private SaobeiTerminalAddRequest initSaobeiTerminalAddRequest(MerchantTerminalVo merchantTerminal) {
        // 创建端创建requst
        SaobeiTerminalAddRequest request = new SaobeiTerminalAddRequest();
        request.setInst_no(ApiConstants.INST_NO);
        request.setStore_code(merchantTerminal.getStoreCode());
        request.setMerchant_no(merchantTerminal.getMerchantNo());
        request.setTerminal_name(merchantTerminal.getTerminalName());
        request.setTrace_no(RandomUtils.getRandom(32));
        return request;
    }

    /**
     * 初始化商户门店信息
     *
     * @param merchantShopEntity
     * @return
     */
    private SaobeiStoreAddRequest initSaobeiStoreAddRequest(MerchantShopEntity merchantShopEntity) {
        // 创建门店 requst
        SaobeiStoreAddRequest request = new SaobeiStoreAddRequest();
        request.setInst_no(ApiConstants.INST_NO);
        request.setMerchant_no(merchantShopEntity.getMerchantCode());
        request.setStore_name(merchantShopEntity.getName());
        request.setStore_addre(merchantShopEntity.getAddress());
        request.setStore_person(merchantShopEntity.getContacts());
        request.setStore_phone(merchantShopEntity.getMobile());
        request.setStore_email(merchantShopEntity.getEmail());
        request.setTrace_no(RandomUtils.getRandom(32));
        return request;
    }

    /**
     * 初始化操作日志信息
     *
     * @param baseInfoDomain
     * @param operDesc       操作描述
     * @param operType       操作类型
     * @return
     */
    private MerchantOperLogEntity initMerchantOperLog(BaseInfoDomain baseInfoDomain, String operDesc, Integer operType) {
        MerchantOperLogEntity merchantOperLogEntity = new MerchantOperLogEntity();
        merchantOperLogEntity.setMerchantNo(baseInfoDomain.getCode());
        merchantOperLogEntity.setRemark(operDesc);
        LocalDateTime now = LocalDateTime.now();
        merchantOperLogEntity.setOperTime(now);
        merchantOperLogEntity.setOperType(operType);
        return merchantOperLogEntity;
    }
}
